#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include "bmock.hpp"
#include "bmock_control_tools_mock.hpp"

static int f(int x) {
	STATIC_MOCK(1, (IN(x)));
}
static void g(int x) {
	STATIC_MOCK_VOID(1, (IN(x)));
}

struct test_exception : public std::exception {
	
};


static const int         x        = 25;
static const std::string s_x      = boost::lexical_cast<std::string>(x);
static const char        s_name[] = "x";

BOOST_AUTO_TEST_CASE(testExceptionControl_Return) {
	const int expected_actual = 11;
	int actual = expected_actual;
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));

	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(s_x,s_x,bmock::message(bmock::ARG_VALUE,s_name),bmock::location(__FILE__,__LINE__+4)));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		BOOST_CHECK_NO_THROW(__BMOCK_EXPECT_THROW_C(c1,new test_exception(),f(x)));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(actual = f(x),test_exception);
		__BMOCK_VERIFY_C(c1);
		BOOST_CHECK_EQUAL(expected_actual,actual);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testExceptionControl_Void) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));

	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(s_x,s_x,bmock::message(bmock::ARG_VALUE,s_name),bmock::location(__FILE__,__LINE__+4)));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		BOOST_CHECK_NO_THROW(__BMOCK_EXPECT_THROW_C(c1,new test_exception(),g(x)));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(g(x),test_exception);
		__BMOCK_VERIFY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(test_bad_set_result) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::INVALID_EXPECT),bmock::location(__FILE__,__LINE__+5)));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		__BMOCK_REPLAY_C(c1);
		c1.set_void_result(bmock::location(__FILE__,__LINE__));
	}
	__BMOCK_VERIFY_C(c);
}

static void k(const void* const buf, const size_t len) {
	STATIC_MOCK_VOID(2,(RAW_MEM(IN,buf,len),IN(len)));
}

static const unsigned char inp_buf[]    = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
static const size_t        L1 = sizeof(inp_buf);
BOOST_AUTO_TEST_CASE(test_RAW_IN_and_in_raw_mem_macro_OK)
{
	bmock::raw_mem rm(inp_buf,L1);
	bmock::raw_len rl_(sizeof(char),L1,0);
	size_t exp_=rl_.get_pad_length()/sizeof(char);
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	__BMOCK_EXPECT_RETURN_C(c,false,t->warn_not_equal(exp_,exp_,bmock::message(bmock::INVALID_IN_RAW_MEM),bmock::location(__FILE__,__LINE__+6)));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(rm.get_value(),rm.get_value(),bmock::message(bmock::ARG_VALUE,"buf"),bmock::location(__FILE__,__LINE__+5)));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(boost::lexical_cast<std::string>(L1),boost::lexical_cast<std::string>(L1),bmock::message(bmock::ARG_VALUE,"len"),bmock::location(__FILE__,__LINE__+4)));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		__BMOCK_EXPECT_C(c1,k(bmock::in_raw_mem(inp_buf,L1),L1));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(k(inp_buf,L1));
		__BMOCK_VERIFY_C(c1);
		
	}
	BMOCK_VERIFY;
}
struct YYY
{
	int i;
	char x;
	int *l;
};

static void k_2(YYY* buf_1, const size_t len_1) {
	STATIC_MOCK_VOID(2,(RAW_MEM(IN,buf_1,len_1),IN(len_1)));
}

static YYY buf_4 [3];

BOOST_AUTO_TEST_CASE(test_RAW_IN_not_void_and_in_raw_mem_macro_OK)
{
	bmock::raw_mem rm(buf_4,3);
	bmock::raw_len rl_(sizeof(YYY),3,0);
	size_t exp_=rl_.get_pad_length()/sizeof(YYY);
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	__BMOCK_EXPECT_RETURN_C(c,false,t->warn_not_equal(exp_,exp_,bmock::message(bmock::INVALID_IN_RAW_MEM),bmock::location(__FILE__,__LINE__+6)));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(rm.get_value(),rm.get_value(),bmock::message(bmock::ARG_VALUE,"buf_1"),bmock::location(__FILE__,__LINE__+5)));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(boost::lexical_cast<std::string>(3),boost::lexical_cast<std::string>(3),bmock::message(bmock::ARG_VALUE,"len_1"),bmock::location(__FILE__,__LINE__+4)));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		__BMOCK_EXPECT_C(c1,k_2(bmock::in_raw_mem(buf_4,3),3));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(k_2(buf_4,3));
		__BMOCK_VERIFY_C(c1);

	}
	BMOCK_VERIFY;
}
